home *** CD-ROM | disk | FTP | other *** search
- /*
- * The original copyright owners of the accompanying source code files have
- * agreed to place such code into the public domain. Accordingly, anyone
- * who receives or obtains a copy of such source code is freely entitled to
- * reproduce, use and otherwise exploit such code (including the right to
- * make derivative works), at his/her own risk and expense, without any
- * obligation or liability to the original copyright owners.
- *
- * We would appreciate (but do not require) that the following message be
- * included in any derivative works:
- *
- * "Portions of this program were developed by Peter Broadwell, Rob Myers
- * and Robin Schaufler while working in Silicon Valley."
- *
- * The accompanying source code files and related documentation materials
- * are distributed on an "AS IS" basis, without any warranties or
- * guarantees of any kind. All implied warranties, including the implied
- * warranties of merchantability and of fitness for any particular purpose,
- * are expressly disclaimed.
- */
- #include "gl.h"
- #include "geom.h"
- #include "class.h"
- #include "selectors.h"
- #include "classIds.h"
- #include "colors.h"
- #include "mbox.h"
- #include "panel.h"
- #include "menu.h"
- #include "pick.h"
- #include "objIds.h"
-
- extern inst *clone();
-
- extern menu menuTemplate;
- extern menu bhmenuTemplate;
- extern choice choiceTemplate;
- extern choicef choicefTemplate;
-
- /*
- * initialize a function menu
- */
- panel *
- makeMenu(list, dad, f, ScrArea, nbuttons, receiver, baseSel, paintObj, lightObj)
- register panel *list, *dad;
- int f;
- register rectangle *ScrArea;
- point2d *nbuttons;
- inst *receiver;
- int baseSel;
- Object paintObj, lightObj;
- {
- register menu *aMenu;
-
- if ((aMenu = (menu *)clone(&menuTemplate)) == NULL)
- return list;
-
- aMenu->base.next = list;
- aMenu->base.kids = NULL;
- aMenu->base.dad = dad;
- aMenu->base.area = *ScrArea;
- aMenu->base.painter = paintObj;
-
- aMenu->flags = f;
- aMenu->nbuttons = *nbuttons;
- aMenu->curVal = 0;
- aMenu->receiver = receiver;
- aMenu->baseSelect = baseSel;
- aMenu->highlight = lightObj;
-
- return (panel *)aMenu;
- }
-
-
- /*
- * initialize a function menu
- */
- panel *
- makeBHMenu(list, dad, f, ScrArea, nbuttons, receiver, baseSel,paintObj,lightObj)
- register panel *list, *dad;
- int f;
- register rectangle *ScrArea;
- point2d *nbuttons;
- inst *receiver;
- int baseSel;
- Object paintObj, lightObj;
- {
- register menu *aMenu;
-
- if ((aMenu = (menu *)clone(&bhmenuTemplate)) == NULL)
- return list;
-
- aMenu->base.next = list;
- aMenu->base.kids = NULL;
- aMenu->base.dad = dad;
- aMenu->base.area = *ScrArea;
- aMenu->base.painter = paintObj;
-
- aMenu->flags = f;
- aMenu->nbuttons = *nbuttons;
- aMenu->curVal = 0;
- aMenu->receiver = receiver;
- aMenu->baseSelect = baseSel;
- aMenu->highlight = lightObj;
-
- return (panel *)aMenu;
- }
-
- /*
- * initialize a multi-choice menu
- */
- panel *
- makeChoice(list, dad, f, ScrArea, nxb,nyb,curb, value,choices,paintObj,lightObj)
- register panel *list, *dad;
- int f;
- register rectangle *ScrArea;
- int nxb,nyb,curb;
- int *value;
- int *choices;
- Object paintObj, lightObj;
- {
- register choice *aChoice;
-
- if ((aChoice = (choice *)clone(&choiceTemplate)) == NULL)
- return list;
-
- aChoice->base.next = list;
- aChoice->base.kids = NULL;
- aChoice->base.dad = dad;
- aChoice->base.area = *ScrArea;
- aChoice->base.painter = paintObj;
-
- aChoice->flags = f;
- aChoice->nbuttons.x = nxb;
- aChoice->nbuttons.y = nyb;
- aChoice->curVal = curb;
- aChoice->baseChoice = choices;
- aChoice->value = value;
- aChoice->highlight = lightObj;
-
- return (panel *)aChoice;
- }
-
-
- /*
- * initialize a floating point multi-choice menu
- */
- panel *
- makeChoicef(list, dad, f, ScrArea, nxb,nyb,curb,value,choices,paintObj,lightObj)
- register panel *list, *dad;
- int f;
- register rectangle *ScrArea;
- int nxb,nyb,curb;
- Coord *value;
- Coord *choices;
- Object paintObj, lightObj;
- {
- register choicef *aChoice;
-
- if ((aChoice = (choicef *)clone(&choicefTemplate)) == NULL)
- return list;
-
- aChoice->base.next = list;
- aChoice->base.kids = NULL;
- aChoice->base.dad = dad;
- aChoice->base.area = *ScrArea;
- aChoice->base.painter = paintObj;
-
- aChoice->flags = f;
- aChoice->nbuttons.x = nxb;
- aChoice->nbuttons.y = nyb;
- aChoice->curVal = curb;
- aChoice->baseChoice = choices;
- aChoice->value = value;
- aChoice->highlight = lightObj;
-
- return (panel *)aChoice;
- }
-
-
- #define interp(a,b,c) ((float)(a)/(float)(b)*(float)(c))
-
-
- /*
- * draw a menu's highlight at hitstruct's position (tentative highlight)
- */
- /* ARGSUSED */
- drawMenu(m, argtype, hit)
- register menu *m;
- long argtype;
- register hitstruct *hit;
- {
- point2d button;
- point2df here;
-
- if (m->highlight) {
- button.x = (int)((float)(hit->x * m->nbuttons.x + 0.5) /
- (float)m->base.area.extent.x);
- button.y = (int)((float)(hit->y * m->nbuttons.y + 0.5) /
- (float)m->base.area.extent.y);
-
- here.x = interp(button.x, m->nbuttons.x, m->base.area.extent.x);
- here.y = interp(button.y, m->nbuttons.y, m->base.area.extent.y);
- globalPointf(m, &here);
- /*
- printf("drawMenu: plotting highlight at %g, %g\n", here.x, here.y);
- printf("drawMenu: menu area %d, %d %d, %d\n",
- m->base.area.orig.x,
- m->base.area.orig.y,
- m->base.area.extent.x,
- m->base.area.extent.y);
- /* */
-
- pushmatrix();
- translate(here.x, here.y, 0.0);
- callobj(m->highlight);
- popmatrix();
- }
- }
-
-
- /*
- * draw a choice's highlight at its current position
- */
- drawChoice(c)
- register choice *c;
- {
- point2d curVal;
-
- if (c->highlight) {
- curVal.x = c->curVal % c->nbuttons.x;
- curVal.y = c->curVal / c->nbuttons.x;
-
- pushmatrix();
- translate(interp(curVal.x, c->nbuttons.x, c->base.area.extent.x),
- interp(curVal.y, c->nbuttons.y, c->base.area.extent.y),
- 0.0);
- callobj(c->highlight);
- popmatrix();
- }
- }
-
-
- /*
- * draw a floating point choice's highlight at its current position
- */
- drawChoicef(c)
- register choicef *c;
- {
- point2d curVal;
-
- if (c->highlight) {
- curVal.x = c->curVal % c->nbuttons.x;
- curVal.y = c->curVal / c->nbuttons.x;
-
- pushmatrix();
- translate(interp(curVal.x, c->nbuttons.x, c->base.area.extent.x),
- interp(curVal.y, c->nbuttons.y, c->base.area.extent.y),
- 0.0);
- callobj(c->highlight);
- popmatrix();
- }
- }
-
-
- /*
- * process a selection on a menu button
- */
- /* ARGSUSED */
- selectMenu(self, argtype, hit)
- register menu *self;
- long argtype;
- register hitstruct *hit;
- {
- point2d button;
-
- button.x = (int)((float)(hit->x * self->nbuttons.x + 0.5) /
- (float)self->base.area.extent.x);
- button.y = (int)((float)(hit->y * self->nbuttons.y + 0.5) /
- (float)self->base.area.extent.y);
-
- self->curVal = button.x + (button.y * self->nbuttons.x);
-
- /*************
- printf("selectMenu: button.x=%d, button.y=%d, curVal=%d\n",
- button.x, button.y, self->curVal);
- printf("selectMenu: sending message %d to object 0x%x\n",
- self->baseSelect + self->curVal, self->receiver);
- /*************/
-
- /* dispatch a message to the menu's client */
- Msg(self->receiver, self->baseSelect + self->curVal,
- INTARG, self->baseSelect + self->curVal);
- }
-
- /*
- * process a selection on a menu button
- */
- /* ARGSUSED */
- cascadeMenu(self, argtype, hit)
- register menu *self;
- long argtype;
- register hitstruct *hit;
- {
- int flags;
- point2d button;
- panel *dad, *kids;
- rectangle scrArea;
-
- button.x = 1;
- button.y = 2;
-
- setrect(&scrArea, self->base.area.orig.x,
- self->base.area.orig.y + self->base.area.extent.y,
- 235, 100);
- makeobj(BHMENUOBJ);
- fishColor(PANEL_WHITE);
- rectfi(0,0, scrArea.extent.x, scrArea.extent.y);
- fishColor(PANEL_GRAY3);
- cmov2i(10, 10);
- charstr("I'm tired of this behavior.");
- cmov2i(20, 10+getheight());
- charstr("Toss it away.");
- cmov2i(10, 10+(scrArea.extent.y>>1));
- charstr("Oops! I didn't mean to do this,");
- cmov2i(20, 10+(scrArea.extent.y>>1)+getheight());
- charstr("honest. Put me back where I was.");
- closeobj();
- makeobj(BHLITEOBJ);
- fishColor(PANEL_GRAY3);
- rectfi(5,5, scrArea.extent.x-10, (scrArea.extent.y>>1)-10);
- closeobj();
- dad = self->base.dad;
- kids = dad->kids;
- flags = NULL;
- dad->kids = makeMenu(kids, dad, flags, &scrArea, &button, self->receiver,
- self->baseSelect, BHMENUOBJ, BHLITEOBJ);
- }
-
-
- /*
- * process a selection on a choice button
- */
- selectChoice(self, argtype, hit)
- register choice *self;
- long argtype;
- register hitstruct *hit;
- {
- point2d button;
-
- button.x = (((hit->x - self->base.area.orig.x) * self->nbuttons.x + 0.5) /
- self->base.area.extent.x);
- button.y = (((hit->y - self->base.area.orig.y) * self->nbuttons.y + 0.5) /
- self->base.area.extent.y);
-
- self->curVal = button.x + (button.y * self->nbuttons.x);
-
- /* draw the current highlight */
- Msg(self, DRAWTRACKER, argtype, hit);
-
- /* printf("selectChoice: button.x=%d, button.y=%d, curVal=%d\n",
- button.x, button.y, self->curVal); /* */
- if (self->value)
- *(self->value) = self->baseChoice[self->curVal];
- }
-
-
- /*
- * process a selection on a floating point choice button
- */
- selectChoicef(self, argtype, hit)
- register choicef *self;
- long argtype;
- register hitstruct *hit;
- {
- point2d button;
-
- button.x = (((hit->x - self->base.area.orig.x) * self->nbuttons.x + 0.5) /
- self->base.area.extent.x);
- button.y = (((hit->y - self->base.area.orig.y) * self->nbuttons.y + 0.5) /
- self->base.area.extent.y);
-
- self->curVal = button.x + (button.y * self->nbuttons.x);
-
- /* draw the current highlight */
- Msg(self, DRAWTRACKER, argtype, hit);
-
- /* printf("selectChoice: button.x=%d, button.y=%d, curVal=%d\n",
- button.x, button.y, self->curVal); /* */
- if (self->value)
- *(self->value) = self->baseChoice[self->curVal];
- }
-
-
- extern panel* curPanel;
- /*
- * end picking on a menu (button goes up on it)
- */
- eselMenu(self, argtype, hit)
- register menu *self;
- long argtype;
- hitstruct *hit;
- {
- /* printf("eselMenu: END SELECT on 0x%x, class %d\n",
- self, ((inst *)self)->myClass->classId); /* */
- if (curPanel == (panel *)self) {
- convertHit(self, hit);
- Msg(self, SELECT, argtype, hit);
- Msg(self, TRANSACT, argtype, hit);
- }
- }
-